<script lang="ts" setup>
import {
  onHide,
  onLoad,
  onPageHide,
  onPageScroll,
  onPullDownRefresh,
  onReachBottom,
  onTabItemTap
} from '@dcloudio/uni-app'
import HomeNav from "@/pages/index/components/HomeNav.vue";
import {getDailyImgListApi, getDailySuggestListApi, getHomeBannerApi, getTheBestListApi} from "@/api/home";
import {reactive, ref, watch} from "vue";
import type {BannerItem, DailySuggestItem} from "@/types/home";
import HotPanel from "@/pages/index/components/HotPanel.vue";
import type {HotAnimalItem, TheBestAnimalItem} from "@/types/hot";
import {getHotListApi} from "@/api/hot";
import TheBestPanel from "@/pages/index/components/TheBestPanel.vue";
import Skeleton from "@/pages/index/components/Skeleton.vue";
import type {ImgError} from "@/types/error";
import {ImgErrorType} from "@/enum/imgErrorType";
import {HotSortType} from "@/enum/hotSortType";
import BannerPanel from "@/pages/index/components/BannerPanel.vue";
import type {Version} from "@/types/version";
import {checkAppVersionApi} from "@/api/common";
import {useIndexListModelStore} from "@/stores/indexListModel";
import {useUserStore} from "@/stores/user";
import {formatDate_yyyy_mm_dd} from "@/utils/time";
import {pushMsg, setBadge} from "@/utils/pushUtil";
import {useBadgeStore} from "@/stores/badgeNum";
import {getNewChatNumApi} from "@/api/chat";
import {getUserDetailApi} from "@/api/user";
import type {DailyImageItem} from "@/types/animals";
import {shuffleArray} from "@/utils/listUtil";

uni.$on('onMsg', (msg: pushMessage) => {
  pushMsg(msg, msg.showType)
})
const isFinish = ref(false)
const networkError = ref(false)
const page = ref(1)
const pageSize = ref(16)
const waterfallList = ref()
uni.$on('noNetwork', () => {
  if (!isFinish.value) {
    networkError.value = true
  }
  uni.showToast({title: '网络异常，请稍检查网络', icon: 'none'})
  uni.stopPullDownRefresh()
})

watch(networkError, (value, oldValue) => {
  // 重新加载页面
  if (!value) {
    return uni.reLaunch({url: '/pages/index/index'})
  }
})
// 下拉刷新
onPullDownRefresh(async () => {
  networkError.value = false
  if (isNoMore.value) {
    return uni.stopPullDownRefresh()
  }

  page.value++
  if (indexModelStore.graphicModel) {
    imagePage++
    // 只有在图集模式才会推荐图集
    await Promise.all([getGuessLikeList(), getDailyImageList()]).then(async () => {
      if (isNoMoreImg) {
        dailyItemList.value = []
      }
      guessLikeList.value?.push(...dailyItemList.value)
      waterfallList.value = await shuffleArray(guessLikeList.value!)
    })
    return uni.stopPullDownRefresh()
  }
  // theBestList.value?.forEach((item)=>item.img=[])
  if (!indexModelStore.graphicModel) {
    await Promise.all([getBannerList(), getHotList(), getTheBestList(), getGuessLikeList()])
  }
  uni.stopPullDownRefresh()
})

/**
 * 点击底部tab下拉刷新
 */
/*onShow(() => {
  setTimeout(() => {
    isRefresh = true
  }, 1000)

})*/

onHide(() => {
  isRefresh = false
})
let isRefresh = false
onTabItemTap((e) => {
  if (!isRefresh) {
    // 第一次进入不需要刷新
    isRefresh = true
    return
  }
  uni.pageScrollTo()
  uni.startPullDownRefresh()
})

const {safeAreaInsets} = uni.getSystemInfoSync()
// 获取轮播图数据
const bannerList = ref<BannerItem[]>([])
const getBannerList = async () => {
  const res = await getHomeBannerApi()
  bannerList.value = res.data
}

const hotPage = ref(1)
// 获取热门推荐数据
const hotList = ref<HotAnimalItem[]>([])
const getHotList = async () => {
  const res = await getHotListApi(HotSortType.SEARCH, hotPage.value, 20)
  if (res.data.data.length < res.data.pageSize) {
    hotPage.value = 1
  } else {
    hotPage.value++
  }
  hotList.value = res.data.data
}

// 获取世界之最
const bestPage = ref(1)
const theBestList = ref<TheBestAnimalItem[]>()
//const colorList = ref<string[]>([])
// uni.showLoading({title: '加载中...'})
const getTheBestList = async () => {
  const res = await getTheBestListApi(bestPage.value, 10)
  theBestList.value = res.data.data
  if (res.data.page * res.data.pageSize >= res.data.total) {
    bestPage.value = 1
  } else {
    bestPage.value++
  }
  uni.hideLoading()
  isFinish.value = true
  // 获取色板
  // const imgUrlList = theBestList.value?.map(item => item.img[0])
  /*  for (let i = 0; i < imgUrlList.length; i++) {
      try {
        const res = await Promise.race([getImageThemeColor(imgUrlList[i], 'mainColorCanvas'), timeout()],)
        colorList.value.push(res)
      } catch (e) {
        //await uni.showToast({title: '网络异常，请稍检查网络后,尝试刷新', icon: 'none',duration: 4000,})
        break;
      }
    }*/
}


// 获取每日推荐
const guessLikeList = ref<DailySuggestItem[]>([])
const date = ref(formatDate_yyyy_mm_dd(new Date()))
const count = ref(0)
const userStore = useUserStore()
const getGuessLikeList = async () => {
  const res = await getDailySuggestListApi(page.value, pageSize.value, date.value)
  if (res.data.page * res.data.pageSize >= res.data.total) {
    isNoMore.value = true
  }
  isFinish.value = true
  if (guessLikeList.value && isLoadMore.value) {
    //  加载更多拼接数据
    return res.data.data
  }
  guessLikeList.value = res.data?.data
}


onLoad(async () => {
  uni.$emit('initCategory')
  getBannerList()
  if (!indexModelStore.graphicModel) {
    getHotList()
    getTheBestList()
  }
  await getGuessLikeList()
  if (indexModelStore.graphicModel) {
    getDailyImageList().then(async () => {
      guessLikeList.value?.push(...dailyItemList.value)
      guessLikeList.value=await shuffleArray(guessLikeList.value!) // 这里一定要对guessList排序
      waterfallList.value = guessLikeList.value
    })
  }
  // #ifdef APP-PLUS
  checkAppVersion()
  // #endif
})

// 加载更多
const isNoMore = ref(false)
const isLoadMore = ref(false)
onReachBottom(async () => {
  if (isLoadMore.value) {
    return
  }
  if (isNoMore.value) {
    uni.showToast({title: '没有更多了', icon: 'none', duration: 4000})
    return
  }
  isLoadMore.value = true
  page.value++
  let newGuessList = await getGuessLikeList()
  if (indexModelStore.graphicModel) {
    imagePage++
    await getDailyImageList().then(() => {
      if (newGuessList && !isNoMoreImg)
        newGuessList?.push(...dailyItemList.value)
      else if (!newGuessList && !isNoMoreImg)
        newGuessList = dailyItemList.value
    })
  }
  const array = await shuffleArray(new Array(...newGuessList!))
  guessLikeList.value?.push(...array)
  waterfallList.value = guessLikeList.value
  isLoadMore.value = false
})

/*图片异常处理*/
const onImgError = (error: ImgError) => {
  switch (error.type) {
    case ImgErrorType.SWIPER_IMG_ERROR:
      bannerList.value![error.index].url = ImgErrorType.ERROR_IMG_URL;
      break;
    case ImgErrorType.HOT_IMG_ERROR:
      hotList.value![error.index].img = ImgErrorType.ERROR_IMG_URL;
      break;
    case ImgErrorType.THE_BEST_IMG_ERROR:
      theBestList.value![error.index].img = ImgErrorType.ERROR_IMG_URL;
      break;
    case ImgErrorType.LIST_IMG_ERROR:
      guessLikeList.value![error.index].img = ImgErrorType.ERROR_IMG_URL;
      break;
    default:
      break;
  }
}


// #ifdef APP-PLUS
//app推送更新
const v = ref<Version>()
const oldV = ref('')
const progress = ref() // 下载进度
const download = ref()
const checkAppVersion = () => {
  uni.getSystemInfo({
    success: async function (res) {
      oldV.value = res.appWgtVersion!
      const resV = await checkAppVersionApi(res.appWgtVersion!)
      v.value = resV.data
      if (v.value?.version !== oldV.value) {
        handleUpdateApp()
      }
    }
  })
}

let downloadTask: any
const handleUpdateApp = () => {
  uni.showModal({
    title: '发现新版本',
    confirmText: '立即更新',
    confirmColor: '#39c5bb',
    content: 'v' + oldV.value + '->' + 'v' + v.value?.version + '\n' + v.value?.desc,
    success: function (res) {
      if (res.cancel) {
        return
      }
      download.value.open()
      // 下载文件
      downloadTask = uni.downloadFile({
        url: v.value?.link!,
        success: function (res) {
          // 下载成功
          if (res.statusCode === 200) {
            // 安装
            plus.runtime.install(res.tempFilePath, {
              force: true
            }, function () {
            }, function (e) {
            })
          }
        },
        complete: function (res) {
          download.value.close()
        }
      })
      downloadTask.onProgressUpdate((res: any) => {
        progress.value = res.progress
        // 满足测试条件，取消下载任务。
      })
    }
  })
}
const handleCloseDownload = () => {
  download.value.close()
  downloadTask.abort()
  uni.showToast({
    title: '已取消更新',
    icon: 'none'
  })
}
// #endif
const moveHandle = () => {
}
const noticeText = ref([
  '欢迎使用萌创cuteヾ(≧▽≦*)o',
  '本软件部分图片及数据来自于网络和网友上传',
  '本软件仅供学习交流使用',
  '请勿用于商业用途，否则后果自负',
  '如有侵权，请联系我们立即删除',
  '联系方式邮箱：elysiawain@163.com'
])
const top = ref(92)
// #ifdef H5
top.value = 60

// #endif

/*-----悬浮按钮切换---*/
const indexModelStore = useIndexListModelStore()
const pattern = {
  color: '#7A7E83',
  backgroundColor: '#fff',
  selectedColor: '#39c5bb',
  buttonColor: '#39c5bb',
  iconColor: '#fff',
  icon: 'color'
}
const content = reactive([{
  iconPath: '/static/pic.png',
  selectedIconPath: '/static/pic-active.png',
  text: '图集',
  active: indexModelStore.graphicModel
},
  {
    iconPath: '/static/text.png',
    selectedIconPath: '/static/text-active.png',
    text: '图文',
    active: !indexModelStore.graphicModel
  },
  {
    iconPath: '/static/hide.png',
    text: '隐藏',
    active: false
  },
])
const trigger: UniHelper.UniFabOnTrigger = async (e) => {
  if (e.index === 0) {
    if (indexModelStore.graphicModel) {
      return
    }
    // 切换为图集模式
    changeModel.value = true
    indexModelStore.graphicModel = true
    content[0].active = true
    content[1].active = false
    count.value = 0
    // 回到顶部
    setTimeout(() => {
      uni.pageScrollTo({
        scrollTop: 0,
        duration: 0
      })
    }, 200)
    await getGuessLikeList()
    await getBannerList()
    setTimeout(() => {
      changeModel.value = false
    }, 500)
  } else if (e.index === 1) {
    if (!indexModelStore.graphicModel) {
      return
    }
    changeModel.value = true
    indexModelStore.graphicModel = false
    content[0].active = false
    content[1].active = true
    setTimeout(() => {
      uni.pageScrollTo({
        scrollTop: 0,
        duration: 0
      })
    }, 200)

    await Promise.all([getBannerList(), getHotList(), getTheBestList(), getGuessLikeList()])
    setTimeout(() => {
      changeModel.value = false
    }, 500)
  } else if (e.index === 2) {
    indexModelStore.showChangeBtn = false
    uni.showToast({
      title: '如需再次切换，可前往我的->设置->首页模式，进行切换',
      icon: 'none',
      duration: 5000,
    })
  }
}
const changeModel = ref(false)

// 回到顶部
const scrollTop = ref(0)
onPageScroll((e) => {
  scrollTop.value = e.scrollTop
})
const backTopStyle = {
  backgroundColor: 'rgba(0,0,0,.6)',
  zIndex: 999,
  // #ifdef H5
  transform: 'translateY(-50px)',
  // #endif
}
const iconStyle = {
  color: '#fff',
  fontSize: '24px',
}

// 日期选择
const calendars = ref()
const confirmCalendars = async (e: any) => {
  // 重新获取每日推荐
  // 将数据归0
  page.value = 1
  isNoMore.value = false
  guessLikeList.value = []
  waterfallList.value = []
  imagePage = 1
  isNoMoreImg = false
  imageList.value = []
  date.value = e.fulldate
  await Promise.all([getGuessLikeList(), getDailyImageList()]).then(async () => {
    guessLikeList.value?.push(...dailyItemList.value)
    waterfallList.value = await shuffleArray(guessLikeList.value!)
  })
}
const noticePopup = ref()
const handleOpenCalendar = () => {
  if (!userStore.checkCalendarNotice) {
    noticePopup.value.open()
  }
  calendars.value.open()
}
// 监听页面切换
onPageHide(() => {
  calendars.value.close()
})
const checkNoNotice = () => {
  userStore.checkCalendarNotice = true
}

const badgeStore = useBadgeStore()
const setNewNum = () => {
  if (!userStore.userInfoData?.token) {
    return
  }
  (async () => {
    try {
      const res = await getNewChatNumApi();
      const userDetailRes = await getUserDetailApi();
      const {data: {newUploadCount, newReplyCount, newLikedCount}} = userDetailRes;
      badgeStore.badge = res.data + newUploadCount + newReplyCount + newLikedCount
      setBadge(badgeStore.badge)
      if (badgeStore.badge === 0) {
        return
      }
      uni.setTabBarBadge({
        index: 3,
        text: badgeStore.badge > 99 ? "99+" : badgeStore.badge.toString(),
      })
    } catch (error) {
      console.error("Failed to update badge:", error);
    }
  })()
}
setNewNum()
const reTry = () => {
  uni.startPullDownRefresh()
}


/************获取图集推荐*****************/
const imageList = ref<DailyImageItem[]>([])
let imagePage = 1
let imagePageSize = 10
let isNoMoreImg: boolean = false
const dailyItemList = ref<DailySuggestItem[]>([])
const getDailyImageList = async () => {
  if (isNoMoreImg) {
    // 当没有数据后直接返回
    return
  }
  const res = await getDailyImgListApi(imagePage, imagePageSize, date.value)
  if (res.data.page * res.data.pageSize >= res.data.total) {
    isNoMoreImg = true
  }
  if (imageList.value && isLoadMore.value) {
    if (res.data.data === null) return
    // 触底加载拼接数组
    imageList.value = [...imageList.value, ...res.data.data]
  } else {
    // 下拉刷新
    if (res.data.data === null) {
      imageList.value = []
      return
    }
    imageList.value = res.data.data
  }
  dailyItemList.value = res.data.data.map((item, index) => {
    let dailyItem: DailySuggestItem = {
      id: item.id.toString(),
      img: item.cover,
      name: item.tags || '',
      desc: '',
      isLike: item.isLike,
      type: 1,
      picNum: item.picNum
    }
    return dailyItem
  })
}

// const waterfallList = computed(() => {
//   return guessLikeList.value?.push(...dailyItemList.value)
// })


/**
 * 控制nav显示
 */
let startMove: number
let endMove: number
let move: number
const isDown = ref(false)
let distanceToTop = 0
const onTouchStart = (e: UniHelper.TouchEvent) => {
  startMove = e.touches[0].clientY!
}
const onTouchEnd = (e: TouchEvent) => {
  endMove = e.changedTouches[0].clientY!
  if (endMove - startMove < 0 && distanceToTop > 150) {
    isDown.value = true
  }
}
const onTouchMove = (e: TouchEvent) => {
  move = e.touches[0].clientY!
  isDown.value = move - startMove < 0 && distanceToTop > 150;
}

onPageScroll((e) => {
  distanceToTop = e.scrollTop
  if (distanceToTop < 150) {
    isDown.value = false
  }
})
</script>

<template>
  <uv-loading-page :loading="changeModel" color="#39c5bb" font-size="48rpx"
                   loading-text="正在切换中..."></uv-loading-page>
  <view>
    <!--   防止滚动穿透 -->
    <view @touchmove.stop.prevent="moveHandle">
      <!--   日期选择 -->
      <wu-calendar
          ref="calendars"
          :color="'#39c5bb'"
          :confirm-color="'#39c5bb'"
          :date="date"
          :insert="false"
          :itemHeight="38"
          :maskClick="true"
          :monthShowCurrentMonth="true"
          @confirm="confirmCalendars"
      >
        <!--        <template v-slot:operation>
                  <view class="flex justify-around align-center "
                        style="height: 40px;width: 100%;border-bottom: #bdbdbd  1px solid; font-size: 16px">
                    <view class="text-gray" @click.stop="cancelCalendar">取消</view>
                    <view class="text-bold text-black">请选择推荐日期</view>
                    <view class="text-awGreen" @click.stop="cancelCalendar">确认</view>
                  </view>
                </template>-->
      </wu-calendar>
    </view>

    <Skeleton v-if="!isFinish && !networkError"></Skeleton>
    <home-nav :date-day="date" :show="!isDown" @openCalendar="handleOpenCalendar"></home-nav>
    <view v-show="isFinish" :scroll-y="true" :style="{ paddingTop: top + 2 + 'px' }" class="scroll-box"
          @touchmove="onTouchMove" @touchstart.stop="onTouchStart" @touchend.stop="onTouchEnd">
      <view v-if="!indexModelStore.graphicModel">
        <BannerPanel :banner-list="bannerList" :is-finish="isFinish" @imgError="onImgError"></BannerPanel>
        <uv-notice-bar :text="noticeText" direction="column" mode="closable"></uv-notice-bar>
        <view v-show="hotList?.length > 0">
          <hot-panel :hot-list="hotList" @imgError="onImgError"></hot-panel>
        </view>
        <the-best-panel ref="best" :the-best-animals-list="theBestList" @imgError="onImgError"></the-best-panel>
        <aw-animals-list :animals-list="guessLikeList" :show-name="true" :top="30" :use-waterfall="true"
                         @imgError="onImgError">
          <template v-slot:title>
            <view class="guess-like-title">
              <image mode="aspectFit" src="/static/guess-like.png"></image>
              猜你喜欢
              <image mode="aspectFit" src="/static/guess-like.png"></image>
            </view>
          </template>
          <template v-slot:footer>
            <view v-show="isLoadMore && !isNoMore">
              <aw-loader :size="24"></aw-loader>
            </view>
            <!-- #ifdef H5 -->
            <a v-show="isNoMore" download="mccute.apk" href="http://cuteworld.top/apk/mccute.apk"
               style="font-size: 16px;color: #8d8d8d;display: flex;justify-content: center">
              下载
              <text style="color: #39c5bb"> App</text>
              体验体验更多内容
            </a>
            <view class="flex justify-center margin-top-sm" style="font-size: 12px;color: #999999;width: 100%">
              <uni-link :href="'https://beian.miit.gov.cn/'" :text="'蜀ICP备2024072963号-1'" font-size="12"
                        show-under-line="false"></uni-link>
            </view>
            <!-- #endif -->
          </template>
        </aw-animals-list>
      </view>


      <view v-else>
        <BannerPanel :banner-list="bannerList" :is-finish="isFinish" @imgError="onImgError"></BannerPanel>
        <aw-animals-list :animals-list="waterfallList" :hide-text="true" :show-name="true" :top="10"
                         :use-waterfall="true" @imgError="onImgError">
          <!--          <template v-slot:title>
                      <view class="guess-like-title">
                        <image mode="aspectFit" src="/static/guess-like.png"></image>
                        每日推荐
                        <image mode="aspectFit" src="/static/guess-like.png"></image>
                      </view>
                    </template>-->
          <template v-slot:footer>
            <view v-show="true" style="width: 100%">
              <aw-loader :size="24" :text="'加载中...'"></aw-loader>
            </view>
            <!-- #ifdef H5 -->
            <a v-show="isNoMore" download="mccute.apk" href="http://cuteworld.top/apk/mccute.apk"
               style="font-size: 16px;color: #8d8d8d;display: flex;justify-content: center">
              下载
              <text style="color: #39c5bb"> App</text>
              体验体验更多内容
            </a>
            <view class="flex justify-center margin-top-sm" style="font-size: 12px;color: #999999;width: 100%">
              <uni-link :href="'https://beian.miit.gov.cn/'" :text="'蜀ICP备2024072963号-1'" font-size="12"
                        show-under-line="false"></uni-link>
            </view>
            <!-- #endif -->
          </template>
        </aw-animals-list>
      </view>
    </view>
  </view>
  <uv-no-network z-index="99" @retry="reTry"></uv-no-network>
  <!--  <canvas id="mainColorCanvas" canvas-id="mainColorCanvas" style="position:fixed;left:100%;">-->
  <!--  </canvas>-->
  <view @touchmove.stop.prevent="moveHandle">
    <uni-popup ref="download" :is-mask-click="false" type="center">
      <view class="flex justify-center align-center flex-column padding-sm"
            style="width: 85vw;min-height: 250rpx;background-color:#fff;border-radius: 20rpx ;gap: 40rpx;position: relative">
        <text class="cuIcon-roundclosefill text-awGreen" style="position: absolute;top: 0;right: 0;font-size: 56rpx"
              @click="handleCloseDownload"></text>
        <view class="text-black text-lg">正在更新，请耐心等待</view>
        <aw-progress :progress="progress"></aw-progress>
      </view>
    </uni-popup>
    <uni-popup ref="noticePopup" :is-mask-click="false" type="center">
      <!--      <view class="flex justify-center align-center flex-column padding-sm"
                  style="width: 85vw;min-height: 250rpx;background-color:#fff;border-radius: 20rpx ;gap: 40rpx;position: relative">
              <view class="text-black text-lg">推荐日期选择后仅会推送 <text class="text-awGreen"> 早于或等于</text>该日期的动物内容</view>
            </view>-->
      <uni-popup-dialog :duration="2000" cancel-text="确认" confirm-text="不再提示" mode="base" type="info"
                        @confirm="checkNoNotice">
        <text>推荐日期选择后仅会推送
          <text class="text-red"> 早于或等于</text>
          该日期的动物内容
        </text>
      </uni-popup-dialog>
    </uni-popup>
  </view>

  <!--    返回顶部-->
  <!-- #ifndef H5 -->
  <uni-transition :show="!isDown" custom-class="u-right">
    <uv-back-top ref="uvBackTop" :custom-style="backTopStyle" :icon-style="iconStyle"
                 :scroll-top="scrollTop"></uv-back-top>
    <view v-if="indexModelStore.showChangeBtn">
      <uni-fab :content="content" :pattern="pattern" direction="vertical" horizontal="right" vertical="bottom"
               @trigger="trigger"></uni-fab>
    </view>
  </uni-transition>
  <!-- #endif -->
  <!-- #ifdef H5 -->
  <uv-back-top ref="uvBackTop" :custom-style="backTopStyle" :icon-style="iconStyle"
               :scroll-top="scrollTop"></uv-back-top>
  <view v-if="indexModelStore.showChangeBtn">
    <uni-fab :content="content" :pattern="pattern" direction="vertical" horizontal="right" vertical="bottom"
             @trigger="trigger"></uni-fab>
  </view>
  <!-- #endif -->



</template>


<style lang="scss">
page {
  background-color: #f1f1f1;
}

.scroll-box {
  height: 100vh;
  box-sizing: border-box;
  padding-top: 80px;

  .guess-like-title {
    font-size: 16px;
    color: #333333;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    image {
      width: 25px;
      height: 25px;
      margin: 0 10px;
    }
  }
}

.hideNav {
  transition: all 0.2s ease-in-out;
  opacity: 0;
}

.showNav {
  opacity: 1;
}

.u-right {
  z-index: 9;
}

//@keyframes slide-top {
//  0% {
//    transform: translateY(0)
//  }
//  50% {
//    opacity: 0.5;
//    transform: translateY(-50px);
//  }
//  100% {
//    transform: translateY(-10px);
//    opacity: 0;
//  }
//}

.transition-box-right {
  position: fixed;
  right: 10px;
  bottom: 5%;
}
</style>
